Skip to content

feat: add Hermes CDP tools for React Native runtime access#14

Open
cryptotavares wants to merge 1 commit into
mainfrom
cryptotavares/add-hermes-cdp
Open

feat: add Hermes CDP tools for React Native runtime access#14
cryptotavares wants to merge 1 commit into
mainfrom
cryptotavares/add-hermes-cdp

Conversation

@cryptotavares

Copy link
Copy Markdown

What is the current state of things and why does it need to change?

The MCP server can drive native UI automation (idb/adb/Appium) but has no
way to inspect the app's JavaScript layer. For a React Native app, a large
share of state and logic lives in the Hermes JS runtime, which native automation
cannot reach. Agents debugging or validating app behavior have no way to
evaluate JavaScript, read runtime state, or diagnose the JS layer.

What is the solution your changes offer and how does it work?

Adds two MCP tools that speak raw Chrome DevTools Protocol
(CDP) to the React Native Hermes runtime via Metro's inspector proxy — on
both iOS and Android (the transport is identical HTTP/WebSocket to Metro; only
the default appId differs):

Tool Description
hermes_cdp Speak raw Chrome DevTools Protocol to the React Native Hermes JS runtime.
hermes_targets List and diagnose the debuggable Hermes targets exposed by Metro.

How it works: the app's Hermes runtime connects out to Metro; Metro exposes
debuggable targets over http://localhost:<metroPort>/json with a per-target
webSocketDebuggerUrl. The server discovers targets, selects the right one, and
speaks real CDP over that WebSocket. A standalone HermesSession holds the
resolved Metro port, expected app bundle id, and the pinned device id
(precedence: per-call param > env var > default), decoupled from DeviceBackend.

Safety model — a single Metro can host multiple apps/simulators, so five
fail-closed checks run before executing CDP:

  1. Strict appId match (no substring, no targets[0] fallback).
  2. HermesInternal identity probe before the user's method.
  3. Device pin on reactNative.logicalDeviceId after first success.
  4. Multi-device ambiguity fails closed rather than guessing.
  5. WebSocket URL validation (ws: protocol, loopback host, matching port).

Destructive methods (Runtime.terminateExecution, Inspector.detached) are
blocked, and the synthetic legacy page is filtered out.

Configuration: HERMES_APP_ID / appId param (defaults io.metamask.MetaMask
iOS, io.metamask Android) and HERMES_METRO_PORT / metroPort param (default
8081). Requires a DEBUG build with Metro running; Node 20 needs
NODE_OPTIONS="--experimental-websocket".

Includes full unit test coverage (session resolution, CDP core, tool handlers)
and README + CHANGELOG updates.

Add hermes_cdp and hermes_targets MCP tools that speak Chrome DevTools
Protocol to the React Native Hermes JS runtime via Metro's inspector
proxy (iOS and Android). Includes standalone HermesSession state for
Metro port, app bundle ID, and device pinning, plus target discovery,
selection, and ambiguity handling.
@cryptotavares cryptotavares requested a review from a team as a code owner July 9, 2026 07:57
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants